#include "pipeline.h"

#include <algorithm>
#include <cctype>
#include <map>
#include <string>
#include <utility>
#include <vector>

namespace cfg
{

// 子校验器规格
struct SubValidatorSpec
{
    int index = -1;   // 对于 v1/v2... 的序号；若为命名段（if/then/else）则保持 -1
    std::string name; // 子校验器名称
    PluginOptions options; // 子校验器选项
};

// 解析形如 v1.name / v1.opt.path 的分组子校验器
static std::vector<SubValidatorSpec>
parse_indexed_sub_validators(const PluginOptions & options)
{
    // 先按组收集，再按序号排序输出
    std::map<int, SubValidatorSpec> groups;
    for (const auto & kv : options)
    {
        const std::string & key = kv.first;
        const std::string & val = kv.second;
        // 期望前缀：v<digits>.
        if (key.size() < 3 || key[0] != 'v' || !std::isdigit(static_cast<unsigned char>(key[1])))
            continue;
        // 提取数字
        size_t pos = 1;
        int idx = 0;
        while (pos < key.size() && std::isdigit(static_cast<unsigned char>(key[pos])))
        {
            idx = idx * 10 + (key[pos] - '0');
            ++pos;
        }
        if (pos >= key.size() || key[pos] != '.')
            continue;
        ++pos; // 跳过点
        std::string rest = key.substr(pos);
        auto & spec = groups[idx];
        spec.index = idx;
        if (rest == "name")
        {
            spec.name = val;
        }
        else if (rest.rfind("opt.", 0) == 0)
        {
            std::string opt_key = rest.substr(4); // 去掉 "opt."
            spec.options[opt_key] = val;
        }
    }
    std::vector<SubValidatorSpec> out;
    out.reserve(groups.size());
    for (auto & it : groups)
    {
        out.emplace_back(std::move(it.second));
    }
    return out;
}

// 解析命名段：<prefix>.name / <prefix>.opt.xxx
static std::optional<SubValidatorSpec>
parse_named_sub_validator(const PluginOptions & options, const std::string & prefix)
{
    SubValidatorSpec spec;
    for (const auto & kv : options)
    {
        const std::string & key = kv.first;
        const std::string & val = kv.second;
        if (key == prefix + ".name")
        {
            spec.name = val;
        }
        else if (key.rfind(prefix + ".opt.", 0) == 0)
        {
            std::string opt_key = key.substr(prefix.size() + 5); // 跳过 "<prefix>.opt."
            spec.options[opt_key] = val;
        }
    }
    if (spec.name.empty() && spec.options.empty())
        return std::nullopt;
    return spec;
}

// 帮助：运行子校验器并收集错误
static void
run_sub_validator(const View & view,
                  const SubValidatorSpec & spec,
                  std::vector<ConfigError> & sub_errors)
{
    auto vd = PluginRegistry::instance().create_validator(spec.name);
    if (!vd)
    {
        sub_errors.emplace_back(
            ConfigError{Errc::Other, std::string("unknown validator: ") + spec.name, {}});
        return;
    }
    vd->validate(view, spec.options, sub_errors);
}

// all_of：所有子校验器均通过（无错误）
class ValidatorAllOf : public IValidator
{
public:
    void validate(const View & view,
                  const PluginOptions & options,
                  std::vector<ConfigError> & out_errors) override
    {
        auto subs = parse_indexed_sub_validators(options);
        if (subs.empty())
            return; // 无子项则视为无需校验

        std::vector<ConfigError> all_sub_errors;
        for (const auto & s : subs)
        {
            std::vector<ConfigError> cur;
            run_sub_validator(view, s, cur);
            if (!cur.empty())
            {
                // 聚合具体错误
                std::move(cur.begin(), cur.end(), std::back_inserter(all_sub_errors));
            }
        }
        if (!all_sub_errors.empty())
        {
            // 全量透传子错误，便于定位具体失败项
            std::move(all_sub_errors.begin(), all_sub_errors.end(), std::back_inserter(out_errors));
        }
    }
};

// any_of：至少一个子校验器通过
class ValidatorAnyOf : public IValidator
{
public:
    void validate(const View & view,
                  const PluginOptions & options,
                  std::vector<ConfigError> & out_errors) override
    {
        auto subs = parse_indexed_sub_validators(options);
        if (subs.empty())
            return;

        bool any_ok = false;
        std::vector<ConfigError> collected_failures;

        for (const auto & s : subs)
        {
            std::vector<ConfigError> cur;
            run_sub_validator(view, s, cur);
            if (cur.empty())
            {
                any_ok = true;
            }
            else
            {
                std::move(cur.begin(), cur.end(), std::back_inserter(collected_failures));
            }
        }

        if (!any_ok)
        {
            // 汇总一条顶层错误，附带失败的详细信息
            ConfigError summary{Errc::Other, "any_of: none matched", {}};
            summary.notes = "all sub-validators failed";
            out_errors.emplace_back(std::move(summary));
            std::move(collected_failures.begin(),
                      collected_failures.end(),
                      std::back_inserter(out_errors));
        }
    }
};

// one_of：恰好一个子校验器通过
class ValidatorOneOf : public IValidator
{
public:
    void validate(const View & view,
                  const PluginOptions & options,
                  std::vector<ConfigError> & out_errors) override
    {
        auto subs = parse_indexed_sub_validators(options);
        if (subs.empty())
            return;

        int ok_count = 0;
        std::vector<ConfigError> collected_failures;

        for (const auto & s : subs)
        {
            std::vector<ConfigError> cur;
            run_sub_validator(view, s, cur);
            if (cur.empty())
                ++ok_count;
            else
                std::move(cur.begin(), cur.end(), std::back_inserter(collected_failures));
        }

        if (ok_count != 1)
        {
            ConfigError summary{Errc::Other, "one_of: expected exactly 1 match", {}};
            summary.notes = std::string("actual matches: ") + std::to_string(ok_count);
            out_errors.emplace_back(std::move(summary));
            std::move(collected_failures.begin(),
                      collected_failures.end(),
                      std::back_inserter(out_errors));
        }
    }
};

// not：子校验器不得通过（若通过则报错）
class ValidatorNot : public IValidator
{
public:
    void validate(const View & view,
                  const PluginOptions & options,
                  std::vector<ConfigError> & out_errors) override
    {
        auto spec_opt = parse_named_sub_validator(options, "not");
        if (!spec_opt)
            return;
        const auto & spec = *spec_opt;

        std::vector<ConfigError> cur;
        run_sub_validator(view, spec, cur);

        if (cur.empty())
        {
            ConfigError e{Errc::Other, "not: condition matched", {}};
            e.notes = "sub-validator passed but must not";
            out_errors.emplace_back(std::move(e));
        }
        else
        {
            // not 条件匹配失败（有错误）即视为通过，不追加具体子错误
        }
    }
};

// if_then_else：条件校验
class ValidatorIfThenElse : public IValidator
{
public:
    void validate(const View & view,
                  const PluginOptions & options,
                  std::vector<ConfigError> & out_errors) override
    {
        auto if_spec = parse_named_sub_validator(options, "if");
        if (!if_spec)
            return; // 未提供条件则不进行任何校验

        std::vector<ConfigError> if_errors;
        run_sub_validator(view, *if_spec, if_errors);

        bool cond_true = if_errors.empty();

        if (cond_true)
        {
            auto then_spec = parse_named_sub_validator(options, "then");
            if (then_spec)
            {
                std::vector<ConfigError> then_errors;
                run_sub_validator(view, *then_spec, then_errors);
                if (!then_errors.empty())
                {
                    std::move(
                        then_errors.begin(), then_errors.end(), std::back_inserter(out_errors));
                }
            }
        }
        else
        {
            auto else_spec = parse_named_sub_validator(options, "else");
            if (else_spec)
            {
                std::vector<ConfigError> else_errors;
                run_sub_validator(view, *else_spec, else_errors);
                if (!else_errors.empty())
                {
                    std::move(
                        else_errors.begin(), else_errors.end(), std::back_inserter(out_errors));
                }
            }
        }
    }
};

// 注册组合校验器
REGISTER_VALIDATOR("all_of", ValidatorAllOf);
REGISTER_VALIDATOR("any_of", ValidatorAnyOf);
REGISTER_VALIDATOR("one_of", ValidatorOneOf);
REGISTER_VALIDATOR("not", ValidatorNot);
REGISTER_VALIDATOR("if_then_else", ValidatorIfThenElse);

} // namespace cfg